export function chooseFiles (accept?: string): Promise<FileList> {
  return new Promise((resolve, reject) => {
    const ele = document.createElement('input')
    ele.setAttribute('type', 'file')
    ele.setAttribute('multiple', 'multiple')
    ele.setAttribute('data-cy', 'choose-files')
    accept && ele.setAttribute('accept', accept)
    ele.addEventListener(
      'change',
      () => {
        resolve(ele.files!)
        document.body.removeChild(ele)
      },
      {
        once: true,
      }
    )
    ele.style.cssText = 'position: fixed; left: -99999px;'
    document.body.appendChild(ele)
    ele.click()
  })
}

export function chooseFolders (): Promise<FileList> {
  return new Promise((resolve, reject) => {
    const ele = document.createElement('input')
    ele.setAttribute('type', 'file')
    ele.setAttribute('multiple', 'multiple')
    ele.setAttribute('webkitdirectory', '')
    ele.setAttribute('directory', '')
    ele.setAttribute('data-cy', 'choose-folders')
    ele.addEventListener(
      'change',
      () => {
        resolve(ele.files!)
        document.body.removeChild(ele)
      },
      {
        once: true,
      }
    )
    ele.style.cssText = 'position: fixed; left: -99999px;'
    document.body.appendChild(ele)
    ele.click()
  })
}

// 需要后端配合
export function downloadFiles (urls: string[]) {
  urls.forEach((u) => {
    const ele = document.createElement('iframe')
    ele.setAttribute('src', u)
    ele.style.display = 'none'
    ele.style.height = '0px'
    document.body.appendChild(ele)
    // Check ready state and remove
  })
}

// export function getQRCode(text: string) {
//   return QRCode.toDataURL(text)
// }

export function copyText (text: string) {
  try {
    return navigator.clipboard.writeText(text)
  } catch (e) {
    const input = document.getElementById('copy')! as HTMLInputElement
    input.value = text
    input.select()
    return document.execCommand('copy')
  }
}

export function copyFiles (blobs: Blob[]) {
  return navigator.clipboard.write(
    blobs.map((blob) => {
      return new window.ClipboardItem({
        [blob.type]: blob,
      })
    })
  )
}

async function handleDirectoryEntry (dirHandle: any, folder: string) {
  const ret: Array<File> = []
  for await (const entry of dirHandle.values()) {
    if (entry.kind === 'file') {
      const file = await entry.getFile()
      file.relativePath = `${folder}/${entry.name}`
      ret.push(file)
    }
    if (entry.kind === 'directory') {
      ret.push(
        ...(await handleDirectoryEntry(entry, `${folder}/${entry.name}`))
      )
    }
  }
  return ret
}

export async function showDirectoryPicker (options?: any) {
  const handle = await window.showDirectoryPicker(options)
  return await handleDirectoryEntry(handle, handle.name)
}
export async function showOpenFilePicker (options?: any) {
  return (await window.showOpenFilePicker(options)).map((i: any) => i.getFile())
}

export function loadImage (src: string): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    let img = new Image()
    // img.setAttribute('crossorigin', 'anonymous')
    img.onload = () => {
      resolve(img)
    }
    img.onerror = reject
    img.src = src
  })
}
export function loadBlob (url: string): Promise<Blob> {
  return fetch(url).then((res) => res.blob())
}
export function loadScript (src: string) {
  const script = document.createElement('script')
  script.setAttribute('async', '')
  script.setAttribute('src', src)
  document.body.appendChild(script)
  return script
}
export function loadLink (href: string) {
  let linkEle = document.createElement('link')
  linkEle.setAttribute('rel', 'stylesheet')
  linkEle.setAttribute('href', href)
  document.head.appendChild(linkEle)
  return linkEle
}
export function compositeImages (
  ...args: Array<string | undefined>
): Promise<string> {
  return new Promise(async (resolve, reject) => {
    const canvas = document.createElement('canvas')
    const context = canvas.getContext('2d')
    for (let url of args) {
      if (url) {
        const image = await loadImage(url)
        const width = image.width
        const height = image.height
        if (canvas.width !== width || canvas.height !== height) {
          canvas.width = width
          canvas.height = height
        }

        context!.drawImage(
          image,
          0,
          0,
          image.width,
          image.height,
          0,
          0,
          canvas.width,
          canvas.height
        )
      }
    }
    resolve(canvas.toDataURL(`image/png`, 1))
  })
}
export async function shotElement (video: any, quality = 1) {
  if (typeof video === 'string') {
    video = await loadImage(video)
  }
  let canvas = document.createElement('canvas')
  canvas.width = video.videoWidth || video.width
  canvas.height = video.videoHeight || video.height
  let ct = canvas.getContext('2d')
  ct!.drawImage(video, 0, 0)
  let icon = canvas.toDataURL('image/jpeg', quality)
  return icon
}

type P = {
  x: number
  y: number
}
export function getDragHandler (
  callback: (
    val: P & {
      finished: boolean
    }
  ) => P,
  modifiers: { stop?: boolean }
) {
  let x = 0
  let y = 0
  const mousemove = (e: MouseEvent) => {
    let ret = callback({
      x: e.x - x,
      y: e.y - y,
      finished: false,
    }) || {
      x: 0,
      y: 0,
    }
    // 缓冲值  未处理的值 逆向时抵消
    x = e.x - ret.x
    y = e.y - ret.y
  }
  const mouseup = (e: MouseEvent) => {
    callback({
      x: e.x - x,
      y: e.y - y,
      finished: true,
    })
    window.removeEventListener('mousemove', mousemove)
    window.removeEventListener('mouseup', mouseup)
  }
  const touchmove = (e: TouchEvent) => {
    if (e.touches.length) {
      const ex = e.touches[0].clientX
      const ey = e.touches[0].clientY
      let ret = callback({
        x: ex - x,
        y: ey - y,
        finished: false,
      }) || {
        x: 0,
        y: 0,
      }
      // 缓冲值  未处理的值 逆向时抵消
      x = ex - ret.x
      y = ey - ret.y
    }
  }
  const touchend = (e: TouchEvent) => {
    if (e.touches.length) {
      const ex = e.touches[0].clientX
      const ey = e.touches[0].clientY
      callback({
        x: ex - x,
        y: ey - y,
        finished: true,
      })
    } else {
      callback({
        x: 0,
        y: 0,
        finished: true,
      })
    }
    window.removeEventListener('touchmove', touchmove)
    window.removeEventListener('touchend', touchend)
  }
  return (e: MouseEvent | TouchEvent) => {
    modifiers.stop && e.stopPropagation()
    if (e instanceof TouchEvent) {
      x = e.touches[0].clientX
      y = e.touches[0].clientY
    } else if (e instanceof MouseEvent) {
      x = e.x
      y = e.y
    }
    e.preventDefault()
    window.addEventListener('mousemove', mousemove)
    window.addEventListener('mouseup', mouseup)
    window.addEventListener('touchmove', touchmove)
    window.addEventListener('touchend', touchend)
  }
}

export function getFilesTotalSize (files: FileList) {
  let size = 0
  for (let i = 0; i < files.length; i++) {
    size += files[i].size
  }
  return size
}

export function getLocale () {
  const defaultLanguage = navigator.language.startsWith('en') ? 'en' : 'zh-cn'
  return localStorage.getItem("locale") || defaultLanguage
}

export function isMobileBrowser () {
  // 获取 User-Agent 字符串
  const userAgent = navigator.userAgent || navigator.vendor || window.opera;

  // 检查是否包含手机或平板的关键字
  return /android|iPad|iPhone|iPod|Opera Mini|IEMobile|WPDesktop/i.test(userAgent);
}

export function requestFullscreen (el: any) {
  if (el.requestFullscreen) {
    el.requestFullscreen();
  } else if (el.mozRequestFullScreen) { // Firefox
    el.mozRequestFullScreen();
  } else if (el.webkitRequestFullscreen) { // Chrome, Safari and Opera
    el.webkitRequestFullscreen();
  } else if (el.msRequestFullscreen) { // IE/Edge
    el.msRequestFullscreen();
  }
}


export function exitFullscreen () {
  const el = document as any
  if (el.exitFullscreen) {
    el.exitFullscreen();
  } else if (el.mozExitFullScreen) { // Firefox
    el.mozExitFullScreen();
  } else if (el.webkitExitFullscreen) { // Chrome, Safari and Opera
    el.webkitExitFullscreen();
  } else if (el.msExitFullscreen) { // IE/Edge
    el.msExitFullscreen();
  }
}